package 字符串;

import java.util.Stack;

//https://www.nowcoder.com/practice/c3120c1c1bc44ad986259c0cf0f0b80e?tpId=295&tqId=44664&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj
public class _BM83_字符串变形 {

	public static void main(String[] args) {
		String str = "This is a sample";
		_BM83_字符串变形 test = new _BM83_字符串变形();
		System.out.println(test.trans(str, 16)+",A:"+(int)'A'+",Z:"+(int)'a');
	}

	/**
	 * 双逆转（推荐使用）
	 * 	step 1：遍历字符串，遇到小写字母，转换成大写，遇到大写字母，转换成小写，遇到空格正常不变。
	 *  step 2：第一次反转整个字符串，这样基本的单词逆序就有了，但是每个单词的字符也是逆的。
	 *  step 3：再次遍历字符串，以每个空间为界，将每个单词反转回正常。
	 */
	public String trans(String s, int n) {
        if(n == 0) return s;
        StringBuilder sb = new StringBuilder();
        for(int i =0;i < n;i++){
            //大小写转换
            char c = s.charAt(i);
            if(c >= 'A' && c<= 'Z'){
                char ret = (char)(c - 'A' + 'a');
                sb.append(ret);
            }else if(c >= 'a' && c <= 'z'){
                char ret = (char)(c - 'a' + 'A');
                sb.append(ret);
            }else{
                //空格直接复制
                sb.append(c);
            }
        }
        
        //翻转整个字符串
        sb.reverse();
        
        for (int i = 0; i < n; i++){
            int j = i;
            //以空格为界，二次翻转
            while(j < n && sb.charAt(j) != ' ') 
                j++;
            String temp = sb.substring(i,j);
            StringBuffer buffer = new StringBuffer(temp);
            temp = buffer.reverse().toString();
            sb.replace(i,j,temp);
            i = j;
        }
        return sb.toString();
    }
	
	/**
	 * 分割字符串+栈（扩展思路）
	 * step 1：遍历字符串，遇到小写字母，转换成大写，遇到大写字母，转换成小写，遇到空格正常不变。
	 * step 2：按照空格把字符串分割成一个个单词.
	 * step 3：遍历分割好的单词，将单词依次存入栈中。
	 * step 4：再从栈中弹出单词，拼接成字符串。
	 */
	public String trans01(String s, int n) {
		if(n == 0) return s;
        StringBuilder sb = new StringBuilder();
        for(int i =0;i < n;i++){
            //大小写转换
            char c = s.charAt(i);
            if(c >= 'A' && c<= 'Z'){
                char ret = (char)(c - 'A' + 'a');
                sb.append(ret);
            }else if(c >= 'a' && c <= 'z'){
                char ret = (char)(c - 'a' + 'A');
                sb.append(ret);
            }else{
                //空格直接复制
                sb.append(c);
            }
            
            /*if(Character.isUpperCase(c)) {
            	sb.append(Character.toLowerCase(c));
            }else if (Character.isLowerCase(c)) {
            	sb.append(Character.toUpperCase(c));
			}else{
                //空格直接复制
                sb.append(c);
            }*/
        }
        
        Stack<String> temp=new Stack<String>();
        for (int i = 0; i < n; i++){
            int j = i;
            //以空格为界，分割单词
            while(j < n && sb.charAt(j) != ' ') 
                j++;
            //单词进栈
            temp.push((String)(sb.substring(i, j))); 
            i = j;
        }
        //排除结尾空格的特殊情况
        if(s.charAt(n - 1) == ' ') 
        	sb = new StringBuilder(" ");
        else
        	sb = new StringBuilder();
        //栈遵循先进后厨，单词顺序是反的
        while(!temp.empty()){  
        	sb.append(temp.peek());
            temp.pop();
            if(!temp.empty())
            	sb.append(" ");
        }
        return sb.toString();
	}
	
	public String trans02(String s, int n) {
		// 本题实际就是把字符串s反转(单词中的字符位置不反转)，遇到空格不变，遇到大写字母变成小写，小写字母变成大写
        StringBuffer res = new StringBuffer(); // 存放最终结果
        int index = 0; // 记录字母应插入的位置
        for (int i = n - 1; i >= 0; i--) {
            char ch = s.charAt(i);
            if (ch == ' ') {
                res.append(" ");
                index = res.length();
            } else {
                // 当前字符是字母
                if (ch >= 'A' && ch <= 'Z') {
                    res.insert(index, (char)(ch + 32)); // 大写字母变为小写，每次都插在index位置
                } else {
                    res.insert(index, (char)(ch - 32)); // 小写字母变为大写，每次都插在index位置
                }
            }
        }
        return res.toString();
	}
}
